// 表达式编辑器工具函数
import type {
  Variable,
  ValidationResult,
  ValidationError,
  ValidationWarning,
  Suggestion,
  TextInsertionContext,
  WordBoundary,
  SuggestionInsertionOptions
} from '../types'

/**
 * 文本插入工具类 - 处理智能文本插入和单词边界检测
 */
export class TextInsertionUtils {
  /**
   * 在指定位置提取单词及其边界信息
   * @param text 完整文本
   * @param position 光标位置
   * @returns 单词边界信息
   */
  static extractWordAtPosition(text: string, position: number): WordBoundary {
    let start = position
    let end = position

    // 查找单词开始位置
    while (start > 0 && /[a-zA-Z0-9_.]/.test(text[start - 1])) {
      start--
    }

    // 查找单词结束位置
    while (end < text.length && /[a-zA-Z0-9_.]/.test(text[end])) {
      end++
    }

    return {
      word: text.substring(start, end),
      start,
      end
    }
  }

  /**
   * 查找单词结束位置
   * @param text 文本内容
   * @param startPosition 开始位置
   * @returns 单词结束位置
   */
  static findWordEnd(text: string, startPosition: number): number {
    let end = startPosition
    while (end < text.length && /[a-zA-Z0-9_.]/.test(text[end])) {
      end++
    }
    return end
  }

  /**
   * 提取光标前的当前单词（部分输入）
   * @param text 光标前的文本
   * @param cursorPosition 光标位置
   * @returns 部分单词
   */
  static extractCurrentWord(text: string, cursorPosition: number): string {
    // 向前查找单词边界
    let start = cursorPosition - 1
    while (start >= 0 && /[a-zA-Z0-9_.]/.test(text[start])) {
      start--
    }
    start++

    // 向后查找单词边界（但不超过光标位置）
    let end = cursorPosition
    while (end < text.length && /[a-zA-Z0-9_.]/.test(text[end])) {
      end++
    }

    return text.substring(start, cursorPosition)
  }

  /**
   * 获取文本插入上下文信息
   * @param text 完整文本内容
   * @param cursorPosition 光标位置
   * @param selectionStart 选择开始位置（可选）
   * @param selectionEnd 选择结束位置（可选）
   * @returns 文本插入上下文
   */
  static getTextInsertionContext(
    text: string,
    cursorPosition: number,
    selectionStart?: number,
    selectionEnd?: number
  ): TextInsertionContext {
    const textBeforeCursor = text.substring(0, cursorPosition)
    const partialWord = this.extractCurrentWord(textBeforeCursor, cursorPosition)

    // 计算单词边界
    const wordStartPosition = cursorPosition - partialWord.length
    const wordEndPosition = this.findWordEnd(text, cursorPosition)

    // 检查是否有选中的文本
    let selectedText: string | undefined
    if (selectionStart !== undefined && selectionEnd !== undefined && selectionStart !== selectionEnd) {
      selectedText = text.substring(selectionStart, selectionEnd)
    }

    return {
      cursorPosition,
      partialWord,
      wordStartPosition,
      wordEndPosition,
      shouldReplace: partialWord.length > 0,
      selectedText
    }
  }

  /**
   * 验证文本插入上下文的有效性
   * @param context 文本插入上下文
   * @param textLength 文本总长度
   * @returns 是否有效
   */
  static validateInsertionContext(context: TextInsertionContext, textLength: number): boolean {
    // 检查位置是否在有效范围内
    if (context.cursorPosition < 0 || context.cursorPosition > textLength) {
      return false
    }

    if (context.wordStartPosition < 0 || context.wordStartPosition > textLength) {
      return false
    }

    if (context.wordEndPosition < 0 || context.wordEndPosition > textLength) {
      return false
    }

    // 检查位置关系是否合理
    if (context.wordStartPosition > context.wordEndPosition) {
      return false
    }

    if (context.cursorPosition < context.wordStartPosition || context.cursorPosition > context.wordEndPosition) {
      return false
    }

    return true
  }

  /**
   * 检查是否应该替换部分文本而不是插入
   * @param context 文本插入上下文
   * @param suggestionValue 建议值
   * @returns 是否应该替换
   */
  static shouldReplacePartialText(context: TextInsertionContext, suggestionValue: string): boolean {
    // 如果没有部分单词，直接插入
    if (!context.partialWord || context.partialWord.length === 0) {
      return false
    }

    // 如果建议值以部分单词开头，应该替换
    if (suggestionValue.toLowerCase().startsWith(context.partialWord.toLowerCase())) {
      return true
    }

    // 如果部分单词是建议值的一部分，应该替换
    if (context.partialWord.length > 0 && suggestionValue.toLowerCase().includes(context.partialWord.toLowerCase())) {
      return true
    }

    return false
  }

  /**
   * 计算插入后的光标位置
   * @param context 文本插入上下文
   * @param suggestionValue 建议值
   * @param suggestionType 建议类型
   * @param isReplacement 是否为替换操作
   * @returns 新的光标位置
   */
  static calculateCursorPosition(
    context: TextInsertionContext,
    suggestionValue: string,
    suggestionType: 'variable' | 'function' | 'operator',
    isReplacement: boolean
  ): number {
    let basePosition: number

    if (isReplacement) {
      basePosition = context.wordStartPosition + suggestionValue.length
    } else {
      basePosition = context.cursorPosition + suggestionValue.length
    }

    // 为函数建议特殊处理光标位置（放在括号之间）
    if (suggestionType === 'function' && suggestionValue.includes('()')) {
      return basePosition - 1 // 光标在括号之间
    }

    return basePosition
  }
}

/**
 * 变量管理器实现
 */
export class VariableManagerImpl {
  constructor(
    public systemVariables: Variable[] = [],
    public formVariables: Variable[] = []
  ) { }

  getAllVariables(): Variable[] {
    return [...this.systemVariables, ...this.formVariables]
  }

  getVariablesByType(type: string): Variable[] {
    return this.getAllVariables().filter(v => v.type === type)
  }

  validateVariableName(name: string): boolean {
    const validNamePattern = /^[a-zA-Z_][a-zA-Z0-9_.]*$/
    return validNamePattern.test(name)
  }

  findVariable(name: string): Variable | undefined {
    return this.getAllVariables().find(v => v.name === name)
  }
}

/**
 * 增强的表达式示例生成器
 */
export class ExampleGenerator {
  // 基础示例
  private static basicExamples = [
    'user.age >= 18',
    'len(user.name) > 0',
    'contains(user.email, "@")',
    'user.role == "admin"'
  ]

  // 日期函数示例
  private static dateExamples = [
    'now().Year() > 2023',
    'now().Month() >= 6',
    'now().After(date("2023-01-01"))',
    'date("2023-12-31").Before(now())'
  ]

  // 数学函数示例
  private static numberExamples = [
    'abs(form.salary - 5000) < 1000',
    'max(form.score1, form.score2) >= 80',
    'round(form.amount / 100) * 100 == form.amount',
    'sqrt(pow(x, 2) + pow(y, 2)) < 10'
  ]

  // 复合表达式示例
  private static complexExamples = [
    'form.score >= 60 && form.status == "active"',
    'now().Year() > 2023 && abs(form.salary - 5000) < 1000'
  ]

  private static exampleTemplates = [
    // 数字比较模板
    { pattern: 'number', template: (name: string) => `${name} > 0` },
    { pattern: 'age', template: (name: string) => `${name} >= 18` },
    { pattern: 'score', template: (name: string) => `${name} >= 60` },
    { pattern: 'count', template: (name: string) => `${name} > 0` },
    { pattern: 'salary', template: (name: string) => `abs(${name} - 5000) < 1000` },

    // 字符串比较模板
    { pattern: 'email', template: (name: string) => `contains(${name}, "@")` },
    { pattern: 'phone', template: (name: string) => `matches(${name}, "^1[3-9]\\\\d{9}$")` },
    { pattern: 'name', template: (name: string) => `len(${name}) > 0` },
    { pattern: 'department', template: (name: string) => `${name} == "IT"` },
    { pattern: 'status', template: (name: string) => `${name} == "active"` },
    { pattern: 'role', template: (name: string) => `${name} == "admin"` },

    // 布尔值模板
    { pattern: 'boolean', template: (name: string) => `${name} == true` },
    { pattern: 'enabled', template: (name: string) => `${name}` },
    { pattern: 'active', template: (name: string) => `${name}` },
    { pattern: 'valid', template: (name: string) => `${name}` },
    { pattern: 'approved', template: (name: string) => `${name} == true` },

    // 数组模板
    { pattern: 'array', template: (name: string) => `len(${name}) > 0` },
    { pattern: 'list', template: (name: string) => `len(${name}) > 0` },
    { pattern: 'skills', template: (name: string) => `len(${name}) > 0` }
  ]

  static generateExample(
    systemVars: Variable[],
    formVars: Variable[]
  ): string {
    const allVars = [...systemVars, ...formVars]

    // 如果没有变量，返回基础示例
    if (allVars.length === 0) {
      return this.getRandomExample(this.basicExamples)
    }

    // 根据变量类型和名称智能选择示例
    const smartExample = this.generateSmartExample(systemVars, formVars)
    if (smartExample) {
      return smartExample
    }

    // 回退到基础示例
    return this.getRandomExample(this.basicExamples)
  }

  /**
   * 获取随机示例
   */
  private static getRandomExample(examples: string[]): string {
    return examples[Math.floor(Math.random() * examples.length)]
  }

  /**
   * 根据变量智能生成示例
   */
  private static generateSmartExample(
    systemVars: Variable[],
    formVars: Variable[]
  ): string | null {
    const allVars = [...systemVars, ...formVars]
    
    // 检查是否有特定类型的变量
    const hasNumberVar = allVars.some(v => v.type === 'number')
    const hasStringVar = allVars.some(v => v.type === 'string')
    const hasBooleanVar = allVars.some(v => v.type === 'boolean')
    
    // 检查是否有特定名称的变量
    const hasAge = allVars.some(v => v.name.includes('age'))
    const hasEmail = allVars.some(v => v.name.includes('email'))
    const hasSalary = allVars.some(v => v.name.includes('salary'))
    const hasScore = allVars.some(v => v.name.includes('score'))
    const hasName = allVars.some(v => v.name.includes('name'))
    const hasRole = allVars.some(v => v.name.includes('role'))
    const hasStatus = allVars.some(v => v.name.includes('status'))
    const hasApproved = allVars.some(v => v.name.includes('approved'))
    
    // 根据变量特征选择合适的示例
    if (hasAge) {
      return 'user.age >= 18'
    }
    if (hasEmail) {
      return 'contains(user.email, "@")'
    }
    if (hasSalary) {
      return 'abs(form.salary - 5000) < 1000'
    }
    if (hasScore) {
      return 'max(form.score1, form.score2) >= 80'
    }
    if (hasName) {
      return 'len(user.name) > 0'
    }
    if (hasRole) {
      return 'user.role == "admin"'
    }
    if (hasStatus) {
      return 'form.status == "active"'
    }
    if (hasApproved) {
      return 'form.approved == true'
    }
    
    // 根据变量类型选择示例
    if (hasNumberVar && hasStringVar) {
      return this.getRandomExample(this.complexExamples)
    }
    if (hasNumberVar) {
      return this.getRandomExample(this.numberExamples)
    }
    if (hasStringVar) {
      return this.getRandomExample(this.basicExamples)
    }
    
    return null
  }

  /**
   * 生成多个示例表达式
   */
  static generateMultipleExamples(
    systemVars: Variable[],
    formVars: Variable[]
  ): string[] {
    const examples: string[] = []

    // 为系统变量生成示例
    examples.push(...this.generateVariableExamples(systemVars))

    // 为表单变量生成示例
    examples.push(...this.generateVariableExamples(formVars))

    return examples.slice(0, 5) // 限制示例数量
  }

  /**
   * 为特定变量列表生成示例
   */
  private static generateVariableExamples(variables: Variable[]): string[] {
    return variables
      .map(variable => this.generateVariableExample(variable))
      .filter(example => example !== null) as string[]
  }

  /**
   * 为单个变量生成示例
   */
  private static generateVariableExample(variable: Variable): string | null {
    // 根据变量名称匹配模板
    const nameTemplate = this.findTemplateByName(variable.name)
    if (nameTemplate) {
      return nameTemplate.template(variable.name)
    }

    // 根据变量类型匹配模板
    const typeTemplate = this.findTemplateByType(variable.type)
    if (typeTemplate) {
      return typeTemplate.template(variable.name)
    }

    // 生成通用示例
    return this.generateGenericExample(variable)
  }

  /**
   * 根据变量名称查找模板
   */
  private static findTemplateByName(name: string): typeof this.exampleTemplates[0] | null {
    const lowerName = name.toLowerCase()

    return this.exampleTemplates.find(template =>
      lowerName.includes(template.pattern) && template.pattern !== 'number' && template.pattern !== 'boolean' && template.pattern !== 'array'
    ) || null
  }

  /**
   * 根据变量类型查找模板
   */
  private static findTemplateByType(type: string): typeof this.exampleTemplates[0] | null {
    const typeMap: Record<string, string> = {
      'number': 'number',
      'boolean': 'boolean',
      'array': 'array',
      'string': 'string'
    }

    const templateType = typeMap[type.toLowerCase()]
    if (!templateType) return null

    return this.exampleTemplates.find(template => template.pattern === templateType) || null
  }

  /**
   * 生成通用示例
   */
  private static generateGenericExample(variable: Variable): string {
    switch (variable.type.toLowerCase()) {
      case 'string':
        return `${variable.name} != ""`
      case 'number':
        return `${variable.name} > 0`
      case 'boolean':
        return `${variable.name} == true`
      case 'array':
        return `len(${variable.name}) > 0`
      case 'object':
        return `${variable.name} != null`
      default:
        return `${variable.name} != null`
    }
  }

  /**
   * 生成默认示例（当没有变量时）
   */
  private static generateDefaultExample(variables: Variable[]): string {
    if (variables.length === 0) {
      return 'user.age > 18 && form.department == "IT"'
    }

    const firstVar = variables[0]
    return this.generateVariableExample(firstVar) || `${firstVar.name} != null`
  }

  /**
   * 获取基础示例
   */
  static getBasicExamples(): string[] {
    return [...this.basicExamples]
  }

  /**
   * 获取日期函数示例
   */
  static getDateExamples(): string[] {
    return [...this.dateExamples]
  }

  /**
   * 获取数学函数示例
   */
  static getNumberExamples(): string[] {
    return [...this.numberExamples]
  }

  /**
   * 获取复合表达式示例
   */
  static getComplexExamples(): string[] {
    return [...this.complexExamples]
  }

  /**
   * 根据类型生成示例
   */
  static generateExampleByType(type: 'basic' | 'date' | 'number' | 'complex' | 'validation'): string {
    switch (type) {
      case 'basic':
        return this.getRandomExample(this.basicExamples)
      case 'date':
        return this.getRandomExample(this.dateExamples)
      case 'number':
        return this.getRandomExample(this.numberExamples)
      case 'complex':
        return this.getRandomExample(this.complexExamples)
      case 'validation':
        return 'len(user.name) > 0 && contains(user.email, "@") && form.approved == true'
      default:
        return this.getRandomExample(this.basicExamples)
    }
  }

  /**
   * 生成条件表达式示例
   */
  static generateConditionalExample(
    systemVars: Variable[],
    formVars: Variable[]
  ): string {
    const smartExample = this.generateSmartExample(systemVars, formVars)
    if (smartExample) {
      return `${smartExample} ? "通过" : "拒绝"`
    }
    return 'user.age >= 18 ? "成年" : "未成年"'
  }

  /**
   * 生成函数调用示例
   */
  static generateFunctionExample(
    systemVars: Variable[],
    formVars: Variable[]
  ): string {
    const stringVars = [...systemVars, ...formVars].filter(v => v.type === 'string')
    const numberVars = [...systemVars, ...formVars].filter(v => v.type === 'number')

    const examples: string[] = []

    if (stringVars.length > 0) {
      const stringVar = stringVars[0]
      examples.push(`len(${stringVar.name}) > 0`)

      if (stringVar.name.includes('email')) {
        examples.push(`contains(${stringVar.name}, "@")`)
      } else if (stringVar.name.includes('name')) {
        examples.push(`startsWith(${stringVar.name}, "张")`)
      }
    }

    if (numberVars.length > 0) {
      const numberVar = numberVars[0]
      examples.push(`${numberVar.name} > 0`)
    }

    return examples.length > 0 ? examples[0] : 'len(user.name) > 0'
  }

  /**
   * 根据上下文生成智能示例
   */
  static generateContextualExample(
    systemVars: Variable[],
    formVars: Variable[],
    context: 'decision' | 'validation' | 'filter' | 'general' = 'general'
  ): string {
    switch (context) {
      case 'decision':
        return this.generateDecisionExample(systemVars, formVars)
      case 'validation':
        return this.generateValidationExample(systemVars, formVars)
      case 'filter':
        return this.generateFilterExample(systemVars, formVars)
      default:
        return this.generateExample(systemVars, formVars)
    }
  }

  private static generateDecisionExample(systemVars: Variable[], formVars: Variable[]): string {
    const examples = this.generateMultipleExamples(systemVars, formVars)

    if (examples.length >= 2) {
      return `${examples[0]} && ${examples[1]}`
    }

    return examples[0] || 'user.role == "admin"'
  }

  private static generateValidationExample(systemVars: Variable[], formVars: Variable[]): string {
    const formStringVars = formVars.filter(v => v.type === 'string')
    const formNumberVars = formVars.filter(v => v.type === 'number')

    if (formStringVars.length > 0) {
      const stringVar = formStringVars[0]
      return `len(${stringVar.name}) >= 2`
    }

    if (formNumberVars.length > 0) {
      const numberVar = formNumberVars[0]
      return `${numberVar.name} >= 0`
    }

    return 'len(form.input) > 0'
  }

  private static generateFilterExample(systemVars: Variable[], formVars: Variable[]): string {
    const allVars = [...systemVars, ...formVars]
    const statusVars = allVars.filter(v =>
      v.name.includes('status') || v.name.includes('state') || v.name.includes('active')
    )

    if (statusVars.length > 0) {
      return `${statusVars[0].name} == "active"`
    }

    return 'item.status == "enabled"'
  }
}

/**
 * 增强的表达式验证器 - 基于expr-lang语法
 */
export class ExpressionValidatorImpl {
  private keywords = [
    'true', 'false', 'null', 'nil', 'and', 'or', 'not', 'in', 'contains',
    'startsWith', 'endsWith', 'matches', 'len', 'all', 'none', 'any', 'one',
    'filter', 'map', 'count',
    // Date Functions (只包含可以独立调用的函数)
    'now', 'date', 'duration',
    // Number Functions
    'abs', 'ceil', 'floor', 'round', 'max', 'min', 'pow', 'sqrt', 'log', 'log10',
    'sin', 'cos', 'tan'
  ]

  // 日期对象方法（只能在日期对象后调用）
  private dateMethods = [
    'Year', 'Month', 'Day', 'Hour', 'Minute', 'Second',
    'Weekday', 'Unix', 'Format', 'Add', 'Sub', 'Before', 'After'
  ]

  private operators = [
    '==', '!=', '<', '>', '<=', '>=', '+', '-', '*', '/', '%', '**',
    '&&', '||', '!', 'and', 'or', 'not', 'in', '?', ':'
  ]

  constructor(private variableManager: VariableManagerImpl) { }

  validateSyntax(expression: string): ValidationResult {
    const errors: ValidationError[] = []
    const warnings: ValidationWarning[] = []

    if (!expression.trim()) {
      return { isValid: true, errors: [], warnings: [] }
    }

    try {
      // 词法分析
      const tokens = this.tokenize(expression)

      // 语法分析
      const syntaxErrors = this.parseSyntax(tokens, expression)
      errors.push(...syntaxErrors)

      // 括号匹配检查
      const bracketResult = this.checkBrackets(expression)
      if (!bracketResult.isValid) {
        errors.push({
          message: '括号不匹配',
          type: 'syntax',
          position: bracketResult.position
        })
      }

      // 操作符检查
      const operatorResult = this.checkOperators(expression)
      if (!operatorResult.isValid) {
        errors.push({
          message: operatorResult.message || '操作符使用错误',
          type: 'syntax',
          position: operatorResult.position
        })
      }

      // 字符串字面量检查
      const stringResult = this.checkStringLiterals(expression)
      if (!stringResult.isValid) {
        errors.push({
          message: '字符串字面量格式错误',
          type: 'syntax',
          position: stringResult.position
        })
      }

      // 数字字面量检查
      const numberResult = this.checkNumberLiterals(expression)
      if (!numberResult.isValid) {
        errors.push({
          message: '数字格式错误',
          type: 'syntax',
          position: numberResult.position
        })
      }

    } catch (error) {
      errors.push({
        message: `语法解析错误: ${error instanceof Error ? error.message : '未知错误'}`,
        type: 'syntax'
      })
    }

    return {
      isValid: errors.length === 0,
      errors,
      warnings
    }
  }

  validateVariables(expression: string, availableVars: Variable[]): ValidationResult {
    const errors: ValidationError[] = []
    const warnings: ValidationWarning[] = []

    // 先移除字符串字面量，避免误识别
    const cleanExpression = this.removeStringLiterals(expression)

    // 提取变量引用（支持点号访问）
    const variablePattern = /\b[a-zA-Z_][a-zA-Z0-9_.]*\b/g
    const matches = cleanExpression.match(variablePattern) || []

    for (const match of matches) {
      // 跳过关键字和函数名
      if (this.isKeywordOrFunction(match)) {
        continue
      }

      // 跳过数字（虽然正则已经排除，但保险起见）
      if (/^\d/.test(match)) {
        continue
      }

      // 检查变量是否定义
      const variable = this.findVariableByPath(match, availableVars)
      if (!variable) {
        errors.push({
          message: `未定义的变量: ${match}`,
          type: 'variable'
        })
      }
    }

    // 移除"变量未使用"的警告，因为在表达式编辑器中这不合适

    return {
      isValid: errors.length === 0,
      errors,
      warnings
    }
  }

  validateTypes(expression: string): ValidationResult {
    const errors: ValidationError[] = []
    const warnings: ValidationWarning[] = []

    try {
      // 基础类型兼容性检查
      const typeErrors = this.checkTypeCompatibility(expression)
      errors.push(...typeErrors)

      // 函数参数类型检查
      const functionErrors = this.checkFunctionArguments(expression)
      errors.push(...functionErrors)

    } catch (error) {
      errors.push({
        message: `类型检查错误: ${error instanceof Error ? error.message : '未知错误'}`,
        type: 'type'
      })
    }

    return {
      isValid: errors.length === 0,
      errors,
      warnings
    }
  }

  /**
   * 完整验证（语法 + 变量 + 类型）
   */
  validateComplete(expression: string, availableVars: Variable[]): ValidationResult {
    const syntaxResult = this.validateSyntax(expression)
    const variableResult = this.validateVariables(expression, availableVars)
    const typeResult = this.validateTypes(expression)

    return {
      isValid: syntaxResult.isValid && variableResult.isValid && typeResult.isValid,
      errors: [
        ...syntaxResult.errors,
        ...variableResult.errors,
        ...typeResult.errors
      ],
      warnings: [
        ...syntaxResult.warnings,
        ...variableResult.warnings,
        ...typeResult.warnings
      ]
    }
  }

  private tokenize(expression: string): string[] {
    // 简化的词法分析器
    const tokenPattern = /("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')|(\d+\.?\d*)|([a-zA-Z_][a-zA-Z0-9_.]*)|([><=!&|+\-*/%()[\]{}?:,])|(\s+)/g
    const tokens: string[] = []
    let match

    while ((match = tokenPattern.exec(expression)) !== null) {
      const token = match[0]
      if (!/^\s+$/.test(token)) { // 跳过空白字符
        tokens.push(token)
      }
    }

    return tokens
  }

  private parseSyntax(tokens: string[], expression: string): ValidationError[] {
    const errors: ValidationError[] = []

    // 检查表达式结构
    if (tokens.length === 0) {
      return errors
    }
    // 检查操作符位置
    for (let i = 0; i < tokens.length; i++) {
      const token = tokens[i]
      const prevToken = tokens[i - 1]
      const nextToken = tokens[i + 1]

      if (this.isBinaryOperator(token)) {
        if (i === 0 || i === tokens.length - 1) {
          errors.push({
            message: `二元操作符 "${token}" 位置错误`,
            type: 'syntax'
          })
        }
      }

      if (this.isUnaryOperator(token)) {
        if (i === tokens.length - 1) {
          errors.push({
            message: `一元操作符 "${token}" 后缺少操作数`,
            type: 'syntax'
          })
        }
      }
    }

    return errors
  }

  private checkBrackets(expression: string): { isValid: boolean; position?: number } {
    const stack: Array<{ char: string; pos: number }> = []
    const pairs: Record<string, string> = { '(': ')', '[': ']', '{': '}' }

    for (let i = 0; i < expression.length; i++) {
      const char = expression[i]

      if (char in pairs) {
        stack.push({ char, pos: i })
      } else if (Object.values(pairs).includes(char)) {
        const last = stack.pop()
        if (!last || pairs[last.char] !== char) {
          return { isValid: false, position: i }
        }
      }
    }

    if (stack.length > 0) {
      return { isValid: false, position: stack[stack.length - 1].pos }
    }

    return { isValid: true }
  }

  private checkOperators(expression: string): { isValid: boolean; position?: number; message?: string } {
    const checks = [
      { pattern: /&&\s*&&/, message: '重复的逻辑与操作符' },
      { pattern: /\|\|\s*\|\|/, message: '重复的逻辑或操作符' },
      { pattern: /==\s*==/, message: '重复的等于操作符' },
      { pattern: /!\s*!/, message: '重复的逻辑非操作符' },
      { pattern: /[><=!]=\s*=/, message: '操作符组合错误' },
      { pattern: /\+\s*\+(?!\+)/, message: '重复的加号' },
      { pattern: /-\s*-(?!-)/, message: '重复的减号' }
    ]

    for (const check of checks) {
      const match = expression.match(check.pattern)
      if (match) {
        return {
          isValid: false,
          position: match.index,
          message: check.message
        }
      }
    }

    return { isValid: true }
  }

  private checkStringLiterals(expression: string): { isValid: boolean; position?: number } {
    const stringPattern = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g
    let match

    while ((match = stringPattern.exec(expression)) !== null) {
      const str = match[0]
      const quote = str[0]

      // 检查字符串是否正确闭合
      if (str.length < 2 || str[str.length - 1] !== quote) {
        return { isValid: false, position: match.index }
      }

      // 检查转义字符
      if (!this.isValidEscapeSequence(str)) {
        return { isValid: false, position: match.index }
      }
    }

    return { isValid: true }
  }

  private checkNumberLiterals(expression: string): { isValid: boolean; position?: number } {
    const numberPattern = /\b\d+\.?\d*\b/g
    let match

    while ((match = numberPattern.exec(expression)) !== null) {
      const num = match[0]

      // 检查数字格式
      if (!/^\d+(\.\d+)?$/.test(num)) {
        return { isValid: false, position: match.index }
      }

      // 检查是否为有效数字
      if (isNaN(Number(num))) {
        return { isValid: false, position: match.index }
      }
    }

    return { isValid: true }
  }

  private checkTypeCompatibility(expression: string): ValidationError[] {
    const errors: ValidationError[] = []

    // 检查比较操作符的类型兼容性
    const comparisonPattern = /(\w+)\s*([><=!]+)\s*(\w+|"[^"]*"|'[^']*'|\d+\.?\d*)/g
    let match

    while ((match = comparisonPattern.exec(expression)) !== null) {
      const [, left, operator, right] = match

      // 简化的类型推断
      const leftType = this.inferType(left)
      const rightType = this.inferType(right)

      if (leftType && rightType && !this.areTypesCompatible(leftType, rightType, operator)) {
        errors.push({
          message: `类型不兼容: ${leftType} ${operator} ${rightType}`,
          type: 'type'
        })
      }
    }

    return errors
  }

  private checkFunctionArguments(expression: string): ValidationError[] {
    const errors: ValidationError[] = []

    // 检查普通函数调用的参数
    const functionPattern = /(\w+)\s*\(\s*([^)]*)\s*\)/g
    let match

    while ((match = functionPattern.exec(expression)) !== null) {
      const [, funcName, args] = match

      const expectedArgsNum = this.getFunctionSignatureNum(funcName)
      if (expectedArgsNum !== null) {
        const actualArgs = args ? args.split(',').map(arg => arg.trim()).filter(arg => arg.length > 0) : []

        if (actualArgs.length !== expectedArgsNum) {
          errors.push({
            message: `函数 ${funcName} 期望 ${expectedArgsNum} 个参数，实际提供 ${actualArgs.length} 个`,
            type: 'type'
          })
        }
      } else {
        // 对于可变参数函数，进行特殊验证
        const actualArgs = args ? args.split(',').map(arg => arg.trim()).filter(arg => arg.length > 0) : []

        if (funcName === 'date') {
          // date函数：1-3个参数
          if (actualArgs.length < 1 || actualArgs.length > 3) {
            errors.push({
              message: `函数 ${funcName} 期望 1-3 个参数，实际提供 ${actualArgs.length} 个`,
              type: 'type'
            })
          }
        } else if (funcName === 'max' || funcName === 'min') {
          // max/min函数：至少1个参数
          if (actualArgs.length < 1) {
            errors.push({
              message: `函数 ${funcName} 至少需要 1 个参数，实际提供 ${actualArgs.length} 个`,
              type: 'type'
            })
          }
        }
      }
    }

    // 检查方法链调用的参数（如 now().Year()）
    const methodChainPattern = /(now\(\)|date\([^)]*\))\s*\.\s*(\w+)\s*\(\s*([^)]*)\s*\)/g
    let methodMatch

    while ((methodMatch = methodChainPattern.exec(expression)) !== null) {
      const [, baseFunction, methodName, args] = methodMatch

      // 检查方法是否是有效的日期方法
      if (this.dateMethods.includes(methodName)) {
        const expectedArgsNum = this.getFunctionSignatureNum(methodName)
        if (expectedArgsNum !== null) {
          const actualArgs = args ? args.split(',').map(arg => arg.trim()).filter(arg => arg.length > 0) : []

          if (actualArgs.length !== expectedArgsNum) {
            errors.push({
              message: `方法 ${methodName} 期望 ${expectedArgsNum} 个参数，实际提供 ${actualArgs.length} 个`,
              type: 'type'
            })
          }
        }
      } else {
        errors.push({
          message: `未知的日期方法: ${methodName}`,
          type: 'type'
        })
      }
    }

    return errors
  }

  private findVariableByPath(path: string, variables: Variable[]): Variable | undefined {
    // 支持点号访问，如 user.name
    const parts = path.split('.')
    const rootVar = variables.find(v => v.name === parts[0])

    if (!rootVar) return undefined
    if (parts.length === 1) return rootVar

    // 简化处理，实际项目中可能需要更复杂的对象属性检查
    return rootVar
  }

  private isKeywordOrFunction(word: string): boolean {
    return this.keywords.includes(word.toLowerCase()) || this.dateMethods.includes(word)
  }

  private isBinaryOperator(token: string): boolean {
    return ['==', '!=', '<', '>', '<=', '>=', '+', '-', '*', '/', '%', '**', '&&', '||', 'and', 'or', 'in'].includes(token)
  }

  private isUnaryOperator(token: string): boolean {
    return ['!', 'not', '-', '+'].includes(token)
  }

  private isValidEscapeSequence(str: string): boolean {
    // 简化的转义字符检查
    const escapePattern = /\\[nrtbf\\'"]/g
    return !str.includes('\\') || escapePattern.test(str)
  }

  private inferType(value: string): string | null {
    if (/^".*"$/.test(value) || /^'.*'$/.test(value)) return 'string'
    if (/^\d+\.?\d*$/.test(value)) return 'number'
    if (['true', 'false'].includes(value.toLowerCase())) return 'boolean'
    if (['null', 'nil'].includes(value.toLowerCase())) return 'null'

    // 尝试从变量管理器中获取类型
    const variable = this.variableManager.findVariable(value)
    return variable?.type || null
  }

  private areTypesCompatible(leftType: string, rightType: string, operator: string): boolean {
    // 简化的类型兼容性检查
    if (leftType === rightType) return true
    if (leftType === 'null' || rightType === 'null') return ['==', '!='].includes(operator)
    if ((leftType === 'number' && rightType === 'string') || (leftType === 'string' && rightType === 'number')) {
      return ['==', '!='].includes(operator)
    }
    return false
  }

  private getFunctionSignatureNum(funcName: string): number | null {
    const signatures: Record<string, number | 'variable'> = {
      // String Functions
      'len': 1,
      'contains': 2,
      'startsWith': 2,
      'endsWith': 2,
      'matches': 2,
      'upper': 1,
      'lower': 1,
      'trim': 1,

      // Date Functions
      'now': 0,
      'date': 'variable', // 1-3 parameters: date(str[, format[, timezone]])
      'duration': 1,
      'Year': 0,
      'Month': 0,
      'Day': 0,
      'Hour': 0,
      'Minute': 0,
      'Second': 0,
      'Weekday': 0,
      'Unix': 0,
      'Format': 1,
      'Add': 1,
      'Sub': 1,
      'Before': 1,
      'After': 1,

      // Number Functions
      'abs': 1,
      'ceil': 1,
      'floor': 1,
      'round': 1,
      'max': 'variable', // variable arguments
      'min': 'variable', // variable arguments
      'pow': 2,
      'sqrt': 1,
      'log': 1,
      'log10': 1,
      'sin': 1,
      'cos': 1,
      'tan': 1
    }

    const signature = signatures[funcName]
    return signature === 'variable' ? null : (signature as number) || null
  }

  /**
   * 移除字符串字面量，避免误识别字符串内容为变量
   */
  private removeStringLiterals(expression: string): string {
    // 移除双引号字符串
    let cleaned = expression.replace(/"(?:[^"\\]|\\.)*"/g, '""')
    // 移除单引号字符串
    cleaned = cleaned.replace(/'(?:[^'\\]|\\.)*'/g, "''")
    return cleaned
  }
}

/**
 * 自动完成提供器
 */
export class AutoCompleteProviderImpl {
  private functions = [
    // String Functions
    {
      name: 'len',
      description: '获取字符串或数组长度',
      example: 'len(user.name)',
      priority: 10
    },
    {
      name: 'contains',
      description: '检查是否包含子字符串',
      example: 'contains(user.email, "@")',
      priority: 9
    },
    {
      name: 'startsWith',
      description: '检查是否以指定字符串开头',
      example: 'startsWith(user.name, "张")',
      priority: 8
    },
    {
      name: 'endsWith',
      description: '检查是否以指定字符串结尾',
      example: 'endsWith(user.email, ".com")',
      priority: 8
    },
    {
      name: 'matches',
      description: '正则表达式匹配',
      example: 'matches(user.phone, "^1[3-9]\\d{9}$")',
      priority: 7
    },
    {
      name: 'upper',
      description: '转换为大写',
      example: 'upper(user.name)',
      priority: 6
    },
    {
      name: 'lower',
      description: '转换为小写',
      example: 'lower(user.email)',
      priority: 6
    },
    {
      name: 'trim',
      description: '去除首尾空格',
      example: 'trim(form.input)',
      priority: 5
    },

    // Date Functions
    {
      name: 'now',
      description: '获取当前时间',
      example: 'now()',
      priority: 9
    },
    {
      name: 'date',
      description: '解析日期字符串，支持格式和时区参数',
      example: 'date("2023-01-01", "2006-01-02", "UTC")',
      priority: 8,
      variableArgs: true
    },
    {
      name: 'duration',
      description: '创建时间间隔',
      example: 'duration("1h30m")',
      priority: 7
    },
    {
      name: 'Year',
      description: '获取年份（用于日期对象）',
      example: 'now().Year()',
      priority: 8,
      isMethod: true
    },
    {
      name: 'Month',
      description: '获取月份（用于日期对象）',
      example: 'now().Month()',
      priority: 8,
      isMethod: true
    },
    {
      name: 'Day',
      description: '获取日期（用于日期对象）',
      example: 'now().Day()',
      priority: 8,
      isMethod: true
    },
    {
      name: 'Hour',
      description: '获取小时（用于日期对象）',
      example: 'now().Hour()',
      priority: 7,
      isMethod: true
    },
    {
      name: 'Minute',
      description: '获取分钟（用于日期对象）',
      example: 'now().Minute()',
      priority: 7,
      isMethod: true
    },
    {
      name: 'Second',
      description: '获取秒数（用于日期对象）',
      example: 'now().Second()',
      priority: 7,
      isMethod: true
    },
    {
      name: 'Weekday',
      description: '获取星期几（用于日期对象）',
      example: 'now().Weekday()',
      priority: 6,
      isMethod: true
    },
    {
      name: 'Unix',
      description: '获取Unix时间戳（用于日期对象）',
      example: 'now().Unix()',
      priority: 6,
      isMethod: true
    },
    {
      name: 'Format',
      description: '格式化日期（用于日期对象）',
      example: 'now().Format("2006-01-02 15:04:05")',
      priority: 8,
      isMethod: true
    },
    {
      name: 'Add',
      description: '添加时间间隔（用于日期对象）',
      example: 'now().Add(duration("1h"))',
      priority: 7,
      isMethod: true
    },
    {
      name: 'Sub',
      description: '减去时间间隔（用于日期对象）',
      example: 'now().Sub(duration("1h"))',
      priority: 7,
      isMethod: true
    },
    {
      name: 'Before',
      description: '检查是否在指定时间之前（用于日期对象）',
      example: 'now().Before(date("2024-01-01"))',
      priority: 6,
      isMethod: true
    },
    {
      name: 'After',
      description: '检查是否在指定时间之后（用于日期对象）',
      example: 'now().After(date("2023-01-01"))',
      priority: 6,
      isMethod: true
    },

    // Number Functions
    {
      name: 'abs',
      description: '获取绝对值',
      example: 'abs(-5)',
      priority: 8
    },
    {
      name: 'ceil',
      description: '向上取整',
      example: 'ceil(4.2)',
      priority: 7
    },
    {
      name: 'floor',
      description: '向下取整',
      example: 'floor(4.8)',
      priority: 7
    },
    {
      name: 'round',
      description: '四舍五入',
      example: 'round(4.5)',
      priority: 8
    },
    {
      name: 'max',
      description: '获取最大值',
      example: 'max(1, 2, 3)',
      priority: 7,
      variableArgs: true
    },
    {
      name: 'min',
      description: '获取最小值',
      example: 'min(1, 2, 3)',
      priority: 7,
      variableArgs: true
    },
    {
      name: 'pow',
      description: '计算幂',
      example: 'pow(2, 3)',
      priority: 6
    },
    {
      name: 'sqrt',
      description: '计算平方根',
      example: 'sqrt(16)',
      priority: 6
    },
    {
      name: 'log',
      description: '计算自然对数',
      example: 'log(10)',
      priority: 5
    },
    {
      name: 'log10',
      description: '计算以10为底的对数',
      example: 'log10(100)',
      priority: 5
    },
    {
      name: 'sin',
      description: '计算正弦值',
      example: 'sin(3.14159/2)',
      priority: 4
    },
    {
      name: 'cos',
      description: '计算余弦值',
      example: 'cos(0)',
      priority: 4
    },
    {
      name: 'tan',
      description: '计算正切值',
      example: 'tan(3.14159/4)',
      priority: 4
    }
  ]

  private operators = [
    { symbol: '==', description: '等于', priority: 10 },
    { symbol: '!=', description: '不等于', priority: 10 },
    { symbol: '>', description: '大于', priority: 9 },
    { symbol: '<', description: '小于', priority: 9 },
    { symbol: '>=', description: '大于等于', priority: 8 },
    { symbol: '<=', description: '小于等于', priority: 8 },
    { symbol: '&&', description: '逻辑与', priority: 7 },
    { symbol: '||', description: '逻辑或', priority: 7 },
    { symbol: '!', description: '逻辑非', priority: 6 }
  ]

  constructor(private variableManager: VariableManagerImpl) { }

  getVariableSuggestions(input: string): Suggestion[] {
    const variables = this.variableManager.getAllVariables()
    const filtered = this.fuzzyFilter(variables, input, (v) => [v.name, v.label])

    return filtered
      .map(v => ({
        label: v.name,
        value: v.name,
        type: 'variable' as const,
        description: v.label,
        meta: {
          type: v.type,
          example: this.generateVariableExample(v),
          priority: this.calculateVariablePriority(v, input)
        }
      }))
      .sort((a, b) => (b.meta?.priority || 0) - (a.meta?.priority || 0))
  }

  getFunctionSuggestions(input: string, context: string = ''): Suggestion[] {
    // 检查是否在日期对象方法调用的上下文中
    const isDateMethodContext = this.isDateMethodContext(context)

    // 过滤函数：如果是日期方法上下文，只显示日期方法；否则排除日期方法
    const availableFunctions = this.functions.filter(f => {
      if (f.isMethod) {
        // 日期方法只在特定上下文中显示
        return isDateMethodContext
      } else {
        // 普通函数只在非日期方法上下文中显示
        return !isDateMethodContext
      }
    })

    const filtered = this.fuzzyFilter(availableFunctions, input, (f) => [f.name])

    return filtered
      .map(f => {
        // 为方法调用（如 now().Year()）特殊处理
        let value = f.name
        if (f.isMethod) {
          // 方法调用，添加括号
          value = `${f.name}()`
        } else if (f.variableArgs) {
          // 可变参数函数，只添加开括号
          value = `${f.name}(`
        } else {
          // 普通函数，添加完整括号
          value = `${f.name}()`
        }

        return {
          label: f.name,
          value: value,
          type: 'function' as const,
          description: f.description,
          meta: {
            example: f.example,
            priority: this.calculateFunctionPriority(f, input),
            isMethod: f.isMethod,
            variableArgs: f.variableArgs
          }
        }
      })
      .sort((a, b) => (b.meta?.priority || 0) - (a.meta?.priority || 0))
  }

  getOperatorSuggestions(context: string): Suggestion[] {
    // 根据上下文智能推荐操作符
    const contextualOperators = this.getContextualOperators(context)

    return contextualOperators
      .map(op => ({
        label: op.symbol,
        value: ` ${op.symbol} `,
        type: 'operator' as const,
        description: op.description,
        meta: {
          priority: op.priority
        }
      }))
      .sort((a, b) => (b.meta?.priority || 0) - (a.meta?.priority || 0))
  }

  /**
   * 获取所有建议（综合变量、函数、操作符）
   */
  getAllSuggestions(input: string, context: string = ''): Suggestion[] {
    const suggestions: Suggestion[] = []

    // 检查是否在日期方法上下文中
    const isDateMethodContext = this.isDateMethodContext(context)

    if (isDateMethodContext) {
      // 在日期方法上下文中，只显示日期方法建议
      suggestions.push(...this.getFunctionSuggestions(input, context))
    } else {
      // 在普通上下文中，显示所有类型的建议
      if (this.shouldShowVariables(input, context)) {
        suggestions.push(...this.getVariableSuggestions(input))
      }

      if (this.shouldShowFunctions(input, context)) {
        suggestions.push(...this.getFunctionSuggestions(input, context))
      }

      if (this.shouldShowOperators(input, context)) {
        suggestions.push(...this.getOperatorSuggestions(context))
      }
    }

    return suggestions
      .sort((a, b) => (b.meta?.priority || 0) - (a.meta?.priority || 0))
      .slice(0, 15) // 限制建议数量
  }

  private fuzzyFilter<T>(
    items: T[],
    input: string,
    getSearchFields: (item: T) => string[]
  ): T[] {
    // 如果输入为空，返回所有项目
    if (!input.trim()) return items

    const searchTerm = input.toLowerCase()

    return items.filter(item => {
      const fields = getSearchFields(item)
      return fields.some(field =>
        field.toLowerCase().includes(searchTerm) ||
        this.fuzzyMatch(field.toLowerCase(), searchTerm)
      )
    })
  }

  private fuzzyMatch(text: string, pattern: string): boolean {
    let patternIndex = 0

    for (let i = 0; i < text.length && patternIndex < pattern.length; i++) {
      if (text[i] === pattern[patternIndex]) {
        patternIndex++
      }
    }

    return patternIndex === pattern.length
  }

  private generateVariableExample(variable: Variable): string {
    switch (variable.type) {
      case 'string':
        return `${variable.name} == "value"`
      case 'number':
        return `${variable.name} > 0`
      case 'boolean':
        return `${variable.name} == true`
      case 'array':
        return `len(${variable.name}) > 0`
      default:
        return `${variable.name} != null`
    }
  }

  private calculateVariablePriority(variable: Variable, input: string): number {
    let priority = 5

    // 精确匹配优先级最高
    if (variable.name.toLowerCase() === input.toLowerCase()) {
      priority += 10
    }

    // 前缀匹配优先级较高
    if (variable.name.toLowerCase().startsWith(input.toLowerCase())) {
      priority += 8
    }

    // 常用变量类型优先级较高
    if (['string', 'number', 'boolean'].includes(variable.type)) {
      priority += 2
    }

    // 系统变量优先级略高于表单变量
    if (this.variableManager.systemVariables.includes(variable)) {
      priority += 1
    }

    return priority
  }

  private calculateFunctionPriority(func: any, input: string): number {
    let priority = func.priority || 5

    // 精确匹配优先级最高
    if (func.name.toLowerCase() === input.toLowerCase()) {
      priority += 10
    }

    // 前缀匹配优先级较高
    if (func.name.toLowerCase().startsWith(input.toLowerCase())) {
      priority += 8
    }

    return priority
  }

  private getContextualOperators(context: string) {
    // 根据上下文推荐合适的操作符
    const lastToken = this.getLastToken(context)

    if (this.isNumericContext(lastToken)) {
      return this.operators.filter(op =>
        ['>', '<', '>=', '<=', '==', '!='].includes(op.symbol)
      )
    }

    if (this.isBooleanContext(lastToken)) {
      return this.operators.filter(op =>
        ['&&', '||', '!'].includes(op.symbol)
      )
    }

    return this.operators
  }

  private shouldShowVariables(input: string, context: string): boolean {
    // 如果输入看起来像变量名，显示变量建议
    return /^[a-zA-Z_]/.test(input) || input === ''
  }

  private shouldShowFunctions(input: string, context: string): boolean {
    // 如果输入看起来像函数名，显示函数建议
    if (/^[a-zA-Z_]/.test(input) || input === '') {
      return true
    }

    // 特殊情况：在日期方法上下文中，即使输入为空也应该显示日期方法
    if (input === '' && this.isDateMethodContext(context)) {
      return true
    }

    return false
  }

  /**
   * 检查是否在日期方法调用的上下文中
   * @param context 上下文字符串
   * @returns 是否在日期方法上下文中
   */
  private isDateMethodContext(context: string): boolean {
    // 检查是否包含 now(). 或 date(). 模式
    const dateMethodPattern = /(now\(\)|date\([^)]*\))\s*\./
    return dateMethodPattern.test(context)
  }

  private shouldShowOperators(input: string, context: string): boolean {
    // 如果上下文表明需要操作符，显示操作符建议
    const lastChar = context.trim().slice(-1)
    return /[a-zA-Z0-9_)]$/.test(lastChar) || input.match(/^[><=!&|]/)
  }

  private getLastToken(context: string): string {
    const tokens = context.trim().split(/\s+/)
    return tokens[tokens.length - 1] || ''
  }

  private isNumericContext(token: string): boolean {
    return /^\d+(\.\d+)?$/.test(token) ||
      this.variableManager.getAllVariables()
        .some(v => v.name === token && v.type === 'number')
  }

  private isBooleanContext(token: string): boolean {
    return ['true', 'false'].includes(token.toLowerCase()) ||
      this.variableManager.getAllVariables()
        .some(v => v.name === token && v.type === 'boolean')
  }

  /**
   * 移除字符串字面量，避免误识别字符串内容为变量
   */
  private removeStringLiterals(expression: string): string {
    // 移除双引号字符串
    let cleaned = expression.replace(/"(?:[^"\\]|\\.)*"/g, '""')
    // 移除单引号字符串
    cleaned = cleaned.replace(/'(?:[^'\\]|\\.)*'/g, "''")
    return cleaned
  }
}